package judesart.app.server;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import judesart.app.client.artwork.ArtworkController;
import judesart.app.domain.Artist;
import judesart.app.domain.Artwork;
import judesart.app.domain.Gallery;
import judesart.app.domain.Project;
import judesart.app.domain.Room;
import judesart.app.domain.RoomArtwork;
import judesart.app.domain.User;
import judesart.app.repository.ArtistDAO;
import judesart.app.repository.ArtworkDAO;
import judesart.app.repository.GalleryDAO;
import judesart.app.repository.ProjectDAO;
import judesart.app.repository.UserDAOImpl;
import judesart.app.service.UserService;
import judesart.app.shared.SearchResult;
import judesart.app.shared.SelectProject;
import judesart.app.shared.ValidationException;
import judesart.common.bean.ApplicationContextProvider;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class ArtworkControllerImpl extends RemoteServiceServlet implements
        ArtworkController {
    private static final long serialVersionUID = 1L;

    private final static Log LOGGER = LogFactory.getLog(UserDAOImpl.class);

    ArtistDAO artistDAO = ApplicationContextProvider.getCtx().getBean(
            ArtistDAO.class);
    UserService userService = ApplicationContextProvider.getCtx().getBean(
            UserService.class);
    ArtworkDAO artworkDAO = ApplicationContextProvider.getCtx().getBean(
            ArtworkDAO.class);
    ProjectDAO projectDAO = ApplicationContextProvider.getCtx().getBean(
            ProjectDAO.class);
    GalleryDAO galleryDAO = ApplicationContextProvider.getCtx().getBean(
            GalleryDAO.class);

    @Override
    public Artwork createArtwork(Artwork artwork) throws ValidationException {
        User user = userService.getCurrentUser();
        if (user != null) {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            artwork.setArtistId(artist.getId());
        }
        return artworkDAO.createArtwork(artwork);
    }

    @Override
    public Artwork updateArtwork(Artwork artwork) throws ValidationException {
        return artworkDAO.updateArtwork(artwork);
    }

    @Override
    public SearchResult<Artwork> searchArtworks(int startAt, int maxElements) {
        User user = userService.getCurrentUser();
        if (user != null) {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            int count = artworkDAO.countArtworks(artist.getId());
            List<Artwork> results = artworkDAO.findArtworks(artist.getId(),
                    startAt, maxElements);
            for (Artwork artwork : results) {
                convertTagsListToSerializable(artwork);
            }
            return new SearchResult<Artwork>(new ArrayList<Artwork>(results), count);
        }
        return null;
    }

    private void convertTagsListToSerializable(Artwork artwork) {
        if (artwork.getTags() != null) {
            String[] tags = artwork.getTags().toArray(
                    new String[artwork.getTags().size()]);
            artwork.setTags(new ArrayList<String>());
            for (String tag : tags) {
                artwork.getTags().add(tag);
            }
        }
    }

    @Override
    public Artwork getArtwork(Long id) {
        Artwork artwork = artworkDAO.findArtworkById(id);
        convertTagsListToSerializable(artwork);
        return artwork;
    }

    @Override
    public void deletePhotoFromArtwork(Long artworkId, Long imageId) {
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        artworkDAO.deleteImageFromArtwork(artwork, imageId);
    }

    @Override
    public void deleteArtwork(Long artworkId) {
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        List<Long> projectIds = projectDAO.findProjectIdsByArtworkId(artworkId);
        for (Long projectId : projectIds) {
            Project project = projectDAO.findProjectById(projectId);
            projectDAO.deleteArtworkFromProject(project, artwork);
        }
        List<Long> galleryIds = galleryDAO.findGalleriesIdsByArtworkId(artworkId);
        for (Long galleryId : galleryIds) {
            Gallery gallery = galleryDAO.findGalleryById(galleryId);
            for (Room room : gallery.getRooms()) {
                for (RoomArtwork roomArtwork : room.getArtworks()) {
                    if (roomArtwork.getArtworkId().equals(artworkId)) {
                        galleryDAO.deleteArtworkFromRoom(room, artwork);
                    }
                }
            }
        }
        artworkDAO.deleteArtwork(artworkId);
    }

    @Override
    public List<SelectProject> getSelectProjectValues(Long artworkId) {
        List<SelectProject> result = new ArrayList<SelectProject>();
        User user = userService.getCurrentUser();
        if (user != null) {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            List<Project> projects = projectDAO.findProjects(artist.getId(), 0,
                    50);
            List<Long> artworkProjectIds = projectDAO.findProjectIdsByArtworkId(artworkId);
            for (Project project : projects) {
                SelectProject value = new SelectProject();
                value.setProjectId(project.getId());
                value.setProjectTitle(project.getTitle());
                boolean hasArtwork = false;
                for (Long artProjId : artworkProjectIds) {
                    if (artProjId.longValue() == project.getId().longValue()) {
                        hasArtwork = true;
                        break;
                    }
                }
                value.setHasArtwork(hasArtwork);
                result.add(value);
            }
        }
        return result;
    }

    @Override
    public Artwork getRandomArtwork(Long userId) {
        Artist artist = artistDAO.findArtistByUserId(userId);
        List<Long> ids = artworkDAO.findArtworkIds(artist.getId());
        int idx = new Random(System.currentTimeMillis()).nextInt(ids.size());
        return artworkDAO.findArtworkById(ids.get(idx));
    }
}
